

inline 
gmm_model::gmm_model(int in_Ncent, field<std::string> in_actions)
:N_cent(in_Ncent), actions(in_actions)
{
}


inline
void
gmm_model::create_gmm_action(int run)
{ 
  //int sc =1;
  //cout << "# clusters: " << N_cent << endl;
  
  for (uword act = 0 ; act < actions.n_rows;  ++act) {
   
    
    //cout << "Calculating GMM for action " << actions(act) << endl;
    stringstream tmp_ss4;
    tmp_ss4 << "./run" << run << "/features/train/feature_vectors_" << actions(act);
    //cout << tmp_ss4.str() << endl;

    mat mat_features;
    mat_features.load( tmp_ss4.str() );
    //cout << "mat_features size " << mat_features.n_rows << " & " << mat_features.n_cols << endl;
    
    
    gmm_diag gmm_model;
    gmm_model.learn(mat_features, N_cent, eucl_dist, static_subset, 20, 0, 1e-5, false);   //Only Kmeans
    gmm_diag bg_model = gmm_model;
    
    
    bool status = gmm_model.learn(mat_features, N_cent, eucl_dist, keep_existing, 20, 5, 1e-5, false);   
    if (status ==false)
    {
      cout << "***********MODEL FAILED**********" << endl;
      cout << "action "  << actions(act) << endl;
      gmm_model = bg_model;
    }

    
    std::stringstream tmp_ss5;
    tmp_ss5 << "./run"<< run << "/gmm_models/Ng" << N_cent << "_" << actions(act); 
    //cout << "Saving GMM in " << tmp_ss5.str() << endl << endl;
    gmm_model.save( tmp_ss5.str() );
  }
  

}


inline 
void 
gmm_model::gmm_multi_action( field<string> peo_test, int run, int L  )
{
  
  double ave_acc=0;
  
  
  mat features_frames; // One feature vector per frame
  uvec real_labels;
  
  //cout << "Testing for GMM with " << N_cent << " centroids" << endl;
 
   vec likelihood_actions;
   vec likelihood_label;
   
  for (uword vi = 0; vi <peo_test.n_rows; ++vi ){ 
    
    std::stringstream tmp_ss4;
    tmp_ss4 << "./run" << run << "/features/multi_test/feat_"<< peo_test(vi);  
    //cout << tmp_ss4.str() << endl;
    
    
    std::stringstream tmp_vec_lab;
    tmp_vec_lab << "./run"<< run << "/features/multi_test/lab_"<< peo_test(vi); 
    //cout << tmp_vec_lab.str()<< endl;
    
    features_frames.load( tmp_ss4.str() );
    real_labels.load( tmp_vec_lab.str(), raw_ascii );
    //real_labels.t().print("real_labels");
    
    
    //conv_to< colvec >::from(x)
    int num_frames = features_frames.n_cols;
    cout << num_frames << endl;
    
    
    mat log_prob;
    log_prob.zeros(num_frames, actions.n_rows);  
    //actions.print("");
    //cout << actions.n_rows << endl;
    
    //cout << "Doing for person " << peo_test(vi) << endl;
    //cout << "num_frames " << num_frames << endl;
    //cout << "num_labels " << real_labels.n_elem << endl;
    
    
    for ( uword fr = 0; fr < num_frames -L +1 ; ++fr)
    //for ( uword fr = 0; fr < num_frames -L  ; fr=fr+5)
       {
	 //cout << ".";
	 mat mat_features;
	 mat_features.zeros(features_frames.n_rows, L);
	 
	 
	 for (uword j = 0; j< L; j++)
	 {
	   //cout << j+fr << " " ;
	   mat_features.col(j) =features_frames.col(j+fr);
  
	 }
	 //cout << endl;
	 
	 //cout << endl;
	 mat likelihood_actions_labels = get_loglikelihoods(mat_features, run);
	 likelihood_actions = likelihood_actions_labels.col(0);
	 likelihood_label = likelihood_actions_labels.col(1);
	 
 
	 
	 //likelihood_actions_scenes.t().print();
	 //cout << endl << "ini " << fr << " fin:" << fr + L-1 << endl;
	 log_prob.rows(fr, fr + L-1).each_row() += likelihood_actions.t();

	 //cout << log_prob.rows(0, fr + L + 5) << endl;
	 //getchar();
	 
	 
       }
       //log_prob.print();
       //cout << "Done here" << endl;
       //getchar();
       uvec est_labels(num_frames);
       
       
       std::stringstream tmp_save_log_prob;
       tmp_save_log_prob<< "./SystemC/run"<<run<<"_log_prob_"<<peo_test(vi) << ".dat";  
       log_prob.save( tmp_save_log_prob.str() , raw_ascii);
       
       
       
       for ( uword i = 0; i < num_frames; ++i)
       {
	 //cout << " " << i;
	 uword index;
	 double max_frame = log_prob.row(i).max(index);
	 //cout << "Log_prob_frame " << i << "= " << log_prob.row(i) << endl;
	 
	 //cout << "Max for " << log_prob.row(i) << " is " << max_frame << " pos: " << index<< endl;
	 
	 est_labels(i) = likelihood_label(index);
	 //cout << "est_labels(i) " << est_labels(i) << endl;
	 
	 
	 
	 //getchar();
	 
       }
       
       std::stringstream tmp_save_estlab;
       tmp_save_estlab<< "./run"<<run<<"/results/est_"<<peo_test(vi);  
       
       est_labels.save(tmp_save_estlab.str(), raw_ascii);
       
       
       std::stringstream tmp_save_real_lab;
       tmp_save_real_lab << "./run"<<run<<"/results/real_"<<peo_test(vi);  
       
       real_labels.save( tmp_save_real_lab.str(), raw_ascii );
       
       uvec comparing = find( est_labels == real_labels);
       double acc = comparing.n_elem;
       cout <<"performance for person "<<peo_test(vi)<<" is "<<setprecision(2)<<fixed<<100*acc/est_labels.n_elem << " %"<<endl;
       ave_acc = ave_acc + 100*acc/est_labels.n_elem;
       //getchar();
  }
  
  /*
  cout << "******************************************************" << endl;
  cout << "Average performance is " << setprecision(2) << fixed << ave_acc/peo_test.n_rows << " %"<<endl;
  cout << "******************************************************" << endl;
  */
  
  ofstream myfile;
  std::stringstream save_perf;
  save_perf << "./run"<<run <<"/results/performance_"<< N_cent <<".txt"; 
  myfile.open( save_perf.str().c_str() );
  myfile <<"Average performance  is " << setprecision(2) << fixed << ave_acc/peo_test.n_rows << " %\n"<<endl; 
  myfile.close();
  
  
}


inline
mat
gmm_model::get_loglikelihoods(mat mat_features, int run)
{
  //cout << "get_loglikelihoods" << endl;
  mat likelihood_actions(actions.n_rows,2);
  vec likelihood_actions_tmp(actions.n_rows); 
  vec likelihood_label(actions.n_rows);
  

  for (uword act_tr = 0; act_tr < actions.n_rows; ++act_tr)
  {
 
    gmm_diag gmm_model;
    std::stringstream tmp_ss5;
    tmp_ss5 << "./run" << run << "/gmm_models/Ng" << N_cent << "_" << actions(act_tr); 
    //cout << tmp_ss5.str() << endl;
    
    gmm_model.load( tmp_ss5.str());
    
    likelihood_actions_tmp (act_tr) = gmm_model.avg_log_p(mat_features);
    likelihood_label (act_tr) = act_tr;

  }

  
  likelihood_actions.col(0) = likelihood_actions_tmp;
  likelihood_actions.col(1) = likelihood_label;
  
  //likelihood_actions.print();
  //cout << "Done. Press a key" << endl;
  //getchar();
  return likelihood_actions;
  
}
